import { useRef, useEffect, useState } from "react";
import * as echarts from "echarts";
import style from './style.module.scss'
import { baseOption } from '@/pages/OverviewPage/map/options'
import http from '@/api/axios'
import '@/api/mock'
import type { MapLevel, RegionData, ChinaMapProps } from '@/Interface/MapInterface'
import type { StoreInfo } from '@/Interface/StoreInfoInterface'
import axios from "axios";
import { useBasicDataStore } from '@/stores/basicDataStore'
import { useHoverStore } from '@/stores/hoverStore'
import { useCompareStore } from '@/stores/compareStore'
import type { ECElementEvent } from 'echarts';
import type { ScatterDataItem } from "@/Interface/MapInterface";
import { message } from 'antd';
import { useCmpDataStore } from "@/stores/cmpDataStore";

const codeCache = new Map<string, string>();

const ChinaMap = ({
  option = baseOption,
  width = "100%",
  height = "100%",
  onRegionChange
}: ChinaMapProps) => {

  const ref = useRef<HTMLDivElement>(null);
  const mapInstance = useRef<echarts.ECharts | null>(null);

  // 状态管理
  const [currentLevel, setCurrentLevel] = useState<MapLevel>("country");
  const [currentRegion, setCurrentRegion] = useState<RegionData>({ code: "100000", name: "中国" });
  const [historyStack, setHistoryStack] = useState<RegionData[]>([]);

  //事件管理,使用选择器订阅具体状态
  const setBasicData = useBasicDataStore((state) => state.setBasicData);
  const setHover = useHoverStore((state) => state.setHover);
  const setCmpData = useCmpDataStore((state) => state.setCmpData);

  const [mockStores, setMockStores] = useState<StoreInfo[]>([]);

  //获取数据
  useEffect(() => {
    http.get('/api/storesData')
      .then(res => {
        setMockStores(res.data.data)
      }).catch(error => {
        console.log(error);
      })
  }, [])

  // 加载地理数据
  const loadGeoData = async (code: string, level: MapLevel) => {
    // 检查缓存
    if (codeCache.has(code)) return codeCache.get(code);
    let url = "";
    switch (level) {
      case "country":
        url = `/geoJson/country.geoJson`;
        break;
      case "province":
        url = `/geoJson/100000/${code}.geoJson`;
        break;
      case "city":
        url = `/geoJson/100000/${currentRegion.parentCode}/${code}.geoJson`;
        break;
    }

    return new Promise<any>((resolve, reject) => {
      const worker = new Worker(new URL('./mapWorker.ts', import.meta.url))
      worker.postMessage(url);
      worker.onmessage = (event) => {
        if (event.data?.type === 'error') {
          worker.terminate();
          reject(event.data.payload);
          return;
        }
        const { data, cache } = event.data;
        cache.forEach(([name, code]: [string, string]) => {
          codeCache.set(name, code);
        })
        worker.terminate();
        resolve(data);
      }
    })
  }

  // 合并配置项
  const getMergedOption = (): echarts.EChartsOption => {
    const mapName = `map_${currentRegion.code}`;

    // 安全获取 series 配置
    const baseSeries = Array.isArray(option?.series)
      ? (option.series[0] as echarts.MapSeriesOption)  // 当series是数组时取第一个元素
      : option?.series
        ? (option.series as echarts.MapSeriesOption)   // 当series是单个配置对象时
        : {};                                          // 默认空对象

    return {
      ...option,
      title: {
        ...option?.title,
        text: currentRegion.name,
      },
      geo: {
        ...baseSeries,
        map: mapName,   // 动态地图名称
        roam: true,    // 确保可缩放平移
        zoom: currentRegion.code === '100000' ? 1.3 : 1,  // 当前视角的缩放比例
        top: currentRegion.code === '100000' ? '28%' : '15%'
      },
      series: [
        {
          ...((baseOption as any).series[1] as echarts.EffectScatterSeriesOption),
          data: mockStores.map(store => ({
            name: store.basicInfo.storeName,
            // 确保坐标转换：字符串转数字
            value: [
              Number(store.basicInfo.coordinates.lng),
              Number(store.basicInfo.coordinates.lat),
            ],
            extra: store // 附加完整数据
          }))
        },
      ],
    };
  };

  // 显示详情弹窗
  const showStoreDetail = (info: StoreInfo) => {
    const compare = useCompareStore.getState().compare;
    if (compare) {
      setCmpData(info)
      sessionStorage.setItem('cmpData', JSON.stringify(info))
    }
    else {
      setBasicData(info)
      sessionStorage.setItem('basicData', JSON.stringify(info))
    }
  };

  // 初始化/更新地图
  const updateMap = async () => {
    if (!ref.current) return;
    try {
      // 加载地理数据
      const geoData = await loadGeoData(currentRegion.code, currentLevel);
      const mapName = `map_${currentRegion.code}`;
      // 注册地图
      echarts.registerMap(mapName, geoData);

      // 清理旧实例
      if (mapInstance.current) {
        mapInstance.current.dispose();
      }
      // 初始化新实例
      mapInstance.current = echarts.init(ref.current);
      mapInstance.current.setOption(getMergedOption());

      // 统一事件处理器
      const handleChartClick = (params: ECElementEvent) => {
        if (params.seriesType === 'effectScatter') {
          // 处理散点点击
          const scatterParams = params as ECElementEvent & {
            data: ScatterDataItem;
          }
          const storeInfo = scatterParams.data.extra as StoreInfo;
          showStoreDetail(storeInfo);
          return;
        } else {
          // 处理地图点击（下钻逻辑）
          handleMapDrillDown(params);
        }
      };

      // 绑定事件
      const bindEvents = () => {
        if (!mapInstance.current) return;
        // 解绑旧事件
        mapInstance.current.off('click');
        mapInstance.current.off('mouseover');
        // 绑定点击事件和悬停事件
        mapInstance.current.on('click', handleChartClick);

        mapInstance.current.on('click', 'series.effectScatter', (params: ECElementEvent) => {
          const scatterParams = params as ECElementEvent & {
            data: ScatterDataItem;
          }
          const storeInfo = scatterParams.data.extra as StoreInfo;
          showStoreDetail(storeInfo);
          setHover(true)
        });
        mapInstance.current.on('mouseover', 'series.effectScatter', (params: ECElementEvent) => {
          const scatterParams = params as ECElementEvent & {
            data: ScatterDataItem;
          }
          const storeInfo = scatterParams.data.extra as StoreInfo;
          showStoreDetail(storeInfo);
        });
      };
      bindEvents();

    } catch (error) {
      console.error("地图加载失败:", error);
    }
  };

  message.config({
    top: 40,
    duration: 2,
    maxCount: 1,
    rtl: true,
    prefixCls: 'my-message',
  });

  const tips = () => message.open({
    type: 'warning',
    content: '暂无数据',
    style: {
      opacity: 0.9
    }
  });


  // 地图下钻处理方法
  const handleMapDrillDown = (params: any) => {
    if (currentLevel === "country") {
      const provinceCode = codeCache.get(params.name) as string;
      if (provinceCode == '710000') {
        tips();
        return;
      }
      const newRegion = {
        code: provinceCode,
        name: params.name,
        parentCode: "100000"
      };
      setHistoryStack([...historyStack, currentRegion]);
      setCurrentLevel("province");
      setCurrentRegion(newRegion);
      onRegionChange?.(newRegion, "province");
    }
    else if (currentLevel === "province") {
      const cityCode = codeCache.get(params.name) as string;
      //检查是否有对应数据
      async function waitData() {
        const url = `/geoJson/100000/${currentRegion.code}/${cityCode}.geoJson`
        try {
          const geoData = await axios(url);
          if (geoData.data.features.length === 0) {
            tips();
            return;
          }
        } catch (error) {
          tips();
          console.log(error);
        }
        const newRegion = {
          code: cityCode,
          name: params.name,
          parentCode: currentRegion.code
        };
        setHistoryStack([...historyStack, currentRegion]);
        setCurrentLevel("city");
        setCurrentRegion(newRegion);
        onRegionChange?.(newRegion, "city");
      }
      waitData();
    }
  };

  // 返回上级
  const handleBack = () => {
    if (historyStack.length === 0) return;

    const prevRegion = historyStack[historyStack.length - 1];
    setHistoryStack(historyStack.slice(0, -1));
    setCurrentRegion(prevRegion);
    setCurrentLevel(prevRegion.parentCode ? "province" : "country");
    onRegionChange?.(prevRegion, prevRegion.parentCode ? "province" : "country");
  };

  // 窗口缩放处理
  useEffect(() => {
    const handleResize = () => mapInstance.current?.resize();
    window.addEventListener("resize", handleResize);
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  // 数据/区域变化时更新
  useEffect(() => {
    updateMap();
  }, [currentRegion, mockStores]);


  return (
    <div>
      <button
        onClick={handleBack}
        disabled={historyStack.length === 0}
        className={style.btn}
      >
        返回上级
      </button>
      <div ref={ref} style={{ width, height }} />
    </div>
  );
};

export default ChinaMap;